﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WXYW.Entities;
using WXYW.DAL;
using WXYW.Model;

namespace WXYW.BLL
{
    public class ApplicationProductService : RepositoryBase
    {
        public List<ApplicationProduct> GetProductByProductType(long typeID)
        {
            Product product = GetEntities<Product>().Where(p=>p.ProductID==typeID).FirstOrDefault();
            ProductType productType = GetEntities<ProductType>().Where(p => p.ProductTypeName.Equals(product.ModelNumber)).FirstOrDefault();

            List<ApplicationProduct> applicationProducts = new List<ApplicationProduct>();
            applicationProducts = GetEntities<ApplicationProduct>(p => p.ProductType.ProductTypeID == productType.ProductTypeID && !string.IsNullOrEmpty(p.ApplicationForm.ApplicationCode)).ToList();

            foreach (ApplicationProduct applicationProduct in applicationProducts)
            {
                if (!applicationProduct.ApplicationFormReference.IsLoaded)
                {
                    applicationProduct.ApplicationFormReference.Load();
                }
                if (!applicationProduct.ProductTypeReference.IsLoaded)
                {
                    applicationProduct.ProductTypeReference.Load();
                }
            }

            return applicationProducts;
        }

        public ApplicationProductHistory GetProductHistoryByID(long ID)
        {
            ApplicationProductHistory appHistory = GetEntities<ApplicationProductHistory>(a => a.ApplicationProductID == ID).FirstOrDefault();
            if (!appHistory.ProblemTypeReference.IsLoaded)
            {
                appHistory.ProblemTypeReference.Load();
            }
            if (!appHistory.ProductTypeReference.IsLoaded)
            {
                appHistory.ProductTypeReference.Load();
            }

            return appHistory;
        }

        public List<ApplicationProduct> GetProductByKeyWord(string keyword)
        {
            List<ApplicationProduct> productList = new List<ApplicationProduct>();
            if (!string.IsNullOrEmpty(keyword))
            {
                IQueryable<ApplicationProduct> productqQueryable = GetEntities<ApplicationProduct>(p => (p.ApplicationForm.ApplicationCode.Contains(keyword)
                    || p.ProductType.ProductTypeName.Contains(keyword) || p.ProductSerialNumber.Contains(keyword)
                    || p.RepairAccessory.Contains(keyword) || p.ProblemType.Name.Contains(keyword)
                    || p.ChangeType.Contains(keyword) || p.ReplaceProductSerialNumber.Contains(keyword))
                    && (p.ApplicationForm.ApplicationType.Equals("R") || p.ApplicationForm.ApplicationType.Equals("D"))
                    ).OrderByDescending(p=>p.ApplicationProductID);
                productList = productqQueryable.ToList();
            }
            else
            {
                productList = GetEntities<ApplicationProduct>(p => p.RepairCompleteDateTime.HasValue && (p.ApplicationForm.ApplicationType.Equals("R") || p.ApplicationForm.ApplicationType.Equals("D"))).OrderByDescending(p => p.ApplicationProductID).ToList();
            }

            foreach (ApplicationProduct product in productList)
            {
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ProblemTypeReference.IsLoaded)
                {
                    product.ProblemTypeReference.Load();
                }
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.UserReference.IsLoaded)
                {
                    product.UserReference.Load();
                }
            }

            return productList;
        }
        public List<ApplicationProduct> GetSRProductByKeyWord(string keyword)
        {
            List<ApplicationProduct> productList = new List<ApplicationProduct>();
            if (!string.IsNullOrEmpty(keyword))
            {
                IQueryable<ApplicationProduct> productqQueryable = GetEntities<ApplicationProduct>(p => (p.ApplicationForm.ApplicationCode.Contains(keyword)
                    || p.ProductType.ProductTypeName.Contains(keyword) || p.ProductSerialNumber.Contains(keyword)
                    || p.RepairAccessory.Contains(keyword) || p.ProblemType.Name.Contains(keyword)
                    || p.ChangeType.Contains(keyword) || p.ReplaceProductSerialNumber.Contains(keyword))
                    && p.RepairCompleteDateTime.HasValue && p.ApplicationForm.ApplicationType.Equals("C")
                    );
                productList = productqQueryable.ToList();
            }
            else
            {
                productList = GetEntities<ApplicationProduct>(p => p.RepairCompleteDateTime.HasValue && p.ApplicationForm.ApplicationType.Equals("C")).ToList();
            }

            foreach (ApplicationProduct product in productList)
            {
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ProblemTypeReference.IsLoaded)
                {
                    product.ProblemTypeReference.Load();
                }
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
            }

            return productList;
        }
        public long AddApplicationProduct(ApplicationProduct product)
        {
            InsertEntity(product);
            return product.ApplicationProductID;
        }

        public ApplicationProduct GetSimpleApplicatonProductByID(long productID)
        {
            return GetEntities<ApplicationProduct>(p => p.ApplicationProductID == productID).FirstOrDefault();
        }

        public ApplicationProduct GetApplicationProductByID(long productID)
        {
            ApplicationProduct product = GetEntities<ApplicationProduct>(p => p.ApplicationProductID == productID).FirstOrDefault();
            if (!product.ProductTypeReference.IsLoaded)
            {
                product.ProductTypeReference.Load();
            }
            if (!product.ApplicationFormReference.IsLoaded)
            {
                product.ApplicationFormReference.Load();
            }
            if (!product.ApplicationForm.UserReference.IsLoaded)
            {
                product.ApplicationForm.UserReference.Load();
            }
            if (!product.ProblemTypeReference.IsLoaded)
            {
                product.ProblemTypeReference.Load();
            }
            if (!product.QuatationForm.IsLoaded)
            {
                product.QuatationForm.Load();
            }
            if (!product.UserReference.IsLoaded)
            {
                product.UserReference.Load();
            }
            return product;
        }

        public List<ApplicationProduct> GetApplicationProduct()
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.IsSubmit == true).OrderBy(p => p.ApplicationProductID);
            foreach (ApplicationProduct product in products)
            {
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
            }

            return products.ToList();
        }

        public List<ApplicationProduct> GetApplicatonProductByFormID(long formID)
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationID == formID);
            foreach (ApplicationProduct product in products)
            {
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ProblemTypeReference.IsLoaded)
                {
                    product.ProblemTypeReference.Load();
                }
                if (!product.UserReference.IsLoaded)
                {
                    product.UserReference.Load();
                }
                if (!product.FPSDRecord.IsLoaded)
                {
                    product.FPSDRecord.Load();
                }
                if (product.User != null && !product.User.ServiceStationReference.IsLoaded)
                {
                    product.User.ServiceStationReference.Load();
                }
            }
            return products.ToList();
        }

        public List<ProductType> GetAllProductType()
        {
            return GetEntities<ProductType>().ToList();
        }

        public ProductType GetProducTypetByID(int id)
        {
            return GetEntities<ProductType>(p => p.ProductTypeID == id).FirstOrDefault();
        }

        public void UpdateApplicationProduct(long productID, int productTypeID, int amount, string productSerialNumber,
            string problemDiscription, string productAppearance, string remark, string repairType, int problemTypeID, string versionNumber)
        {
            ApplicationProduct product = GetEntities<ApplicationProduct>(p => p.ApplicationProductID == productID).FirstOrDefault();
            product.ProductType = GetProducTypetByID(productTypeID);
            product.ProductCount = amount;
            product.ProductSerialNumber = productSerialNumber;
            product.ProductProblemDescription = problemDiscription;
            product.ProductAppearance = productAppearance;
            product.ReceiveRemark = remark;
            product.ProductRepairType = repairType;
            product.ProductVersionNumber = versionNumber;
            product.ProblemType = GetEntities<ProblemType>().Where(p => p.ID == problemTypeID).FirstOrDefault();
            UpdateEntity(product);
        }

        //public void DistributeApplicationProduct(long productID, string repairType, int engineerID)
        //{
        //    ApplicationProduct product = GetEntities<ApplicationProduct>(p => p.ApplicationProductID == productID).FirstOrDefault();
        //    product.ProductRepairType = repairType;
        //    product.User = GetEntities<User>(u => u.UserID == engineerID).FirstOrDefault();
        //    product.Status = "待修";
        //    product.DistributeDateTime = DateTime.Now;
        //    UpdateEntity(product);
        //}

        public void DistributeApplicationProduct(long productID, string repairType, int engineerID, DateTime dateTime)
        {
            ApplicationProduct product = GetEntities<ApplicationProduct>(p => p.ApplicationProductID == productID).FirstOrDefault();
            User engineer = GetEntities<User>(u => u.UserID == engineerID).FirstOrDefault();
            if (!product.UserReference.IsLoaded)
            {
                product.UserReference.Load();
            }
            DateTime distributeDateTime = DateTime.Now;            
            product.ProductRepairType = repairType;
            product.User = engineer;
            product.Status = "待修";
            product.DistributeDateTime = distributeDateTime;
            product.ProductPurchaseDateTime = dateTime;

            UpdateEntity(product);            
        }

        public void UpdateProduct(ApplicationProduct product)
        {
            UpdateEntity(product);
        }

        private bool IsFinishConfirmQuatation(ApplicationForm applicationForm)
        {
            bool flug = true;
            if (!applicationForm.ApplicationProduct.IsLoaded)
            {
                applicationForm.ApplicationProduct.Load();
            }
            foreach (ApplicationProduct product in applicationForm.ApplicationProduct)
            {
                if (product.IsDecideToRepair == null && product.ProductRepairType == "保外")
                {
                    flug = false;
                }
            }

            return flug;
        }

        public void DeleteQuatationFormByID(long quatationID)
        {
            DeleteEntity<QuatationForm>(q => q.ID == quatationID, Guid.Empty);
        }

        public void DeleteQuatationFormByProductID(long productID)
        {
            DeleteEntities<QuatationForm>(q => q.ApplicationProduct.ApplicationProductID == productID, Guid.Empty);
        }

        public List<QuatationForm> GetQuatationFormByProductID(long productID)
        {
            return GetEntities<QuatationForm>(q => q.ApplicationProduct.ApplicationProductID == productID).ToList();
        }

        public List<ConfirmQuatationProductModel> GetQuatationProducts(long applicationID)
        {
            List<ConfirmQuatationProductModel> productModels = new List<ConfirmQuatationProductModel>();
            //IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationID == applicationID && (p.Status == "报价确认中" || p.Status == "返厂-待客户报价确认"));
            //IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationID == applicationID && p.IsQuotePrice.HasValue && p.IsQuotePrice.Value && (!p.IsDecideToRepair.HasValue || (p.IsDecideToRepair.HasValue && !p.IsDecideToRepair.Value)));
            //IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationID == applicationID && p.IsQuotePrice.HasValue && p.IsQuotePrice.Value && 
            //    (!p.IsDecideToRepair.HasValue || p.Status.Equals("报价确认中")));
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>().Where(p => p.ApplicationForm.ApplicationID == applicationID &&
                p.QuotationDateTime.HasValue );
            foreach (ApplicationProduct product in products)
            {
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.UserReference.IsLoaded)
                {
                    product.UserReference.Load();
                }
                ConfirmQuatationProductModel model = new ConfirmQuatationProductModel();
                model.ApplicationProductID = product.ApplicationProductID;
                model.ProductType = product.ProductType.ProductTypeName;
                model.SerialNumber = product.ProductSerialNumber;
                model.ReapairAccessory = string.Empty;
                model.Cost = 0;
                model.BLXX = product.BLXX;
                model.ProblemDescription = product.ProductProblemDescription;
                model.isConfirmRepair = product.IsDecideToRepair;
                model.Engineer = product.User.ContactPerson;
                if (product.ApplySpecialService.HasValue && product.ApplySpecialService.Value)
                {
                    model.ApplySpecialService = true;
                }
                else
                {
                    model.ApplySpecialService = false;
                }

                if (!product.QuatationForm.IsLoaded)
                {
                    product.QuatationForm.Load();
                }
                foreach (QuatationForm quaForm in product.QuatationForm)
                {
                    model.ReapairAccessory += "," + quaForm.AccessoryName;
                    model.Cost += quaForm.Cost;
                    if (quaForm.IsBWBA.HasValue && quaForm.IsBWBA == true)
                    {
                        model.IsBWBA = "保外备案";
                    }
                }
                if (!string.IsNullOrEmpty(model.ReapairAccessory))
                {
                    model.ReapairAccessory = model.ReapairAccessory.Substring(1);
                }

                if (!product.ReturnToFactoryForm.IsLoaded)
                {
                    product.ReturnToFactoryForm.Load();
                }
                if (product.ReturnToFactoryForm.Count > 0)
                {
                    model.IsReturnToFactory = true;
                }
                model.ProductRepairType = product.ProductRepairType;

                if (!product.ReturnToFactoryForm.IsLoaded)
                {
                    product.ReturnToFactoryForm.Load();
                }
                if (!product.SpecialServiceProduct.IsLoaded)
                {
                    product.SpecialServiceProduct.Load();
                }
                if (product.ReturnToFactoryForm.Count > 0)
                {
                    model.ReturnToFactoryStatus = "是";
                }
                else
                {
                    model.ReturnToFactoryStatus = "否";
                }
                if (product.SpecialServiceProduct.Count > 0)
                {
                    model.SpecialServiceStatus = "是";
                    //SpecialServiceProduct specialServiceProduct = product.SpecialServiceProduct.FirstOrDefault();
                    //if (!specialServiceProduct.SpecialServiceFormReference.IsLoaded)
                    //{
                    //    specialServiceProduct.SpecialServiceFormReference.Load();
                    //}
                    //switch (specialServiceProduct.SpecialServiceForm.Status)
                    //{
                    //    case "-1":
                    //        model.SpecialServiceStatus = "特服申请-被驳回";
                    //        break;
                    //    case "1":
                    //        model.SpecialServiceStatus = "特服申请-待定义";
                    //        break;
                    //    case "2":
                    //        model.SpecialServiceStatus = "特服申请-待填";
                    //        break;
                    //    case "3":
                    //        model.SpecialServiceStatus = "等待初审人签字";
                    //        break;
                    //    case "4":
                    //        model.SpecialServiceStatus = "等待终审人签字";
                    //        break;
                    //    case "5":
                    //        model.SpecialServiceStatus = "等待加签人签字";
                    //        break;
                    //    case "6":
                    //        model.SpecialServiceStatus = "审批完成";
                    //        break;
                    //}
                }
                else
                {
                    model.SpecialServiceStatus = "否";
                }
                productModels.Add(model);                
            }

            return productModels;
        }

        public ApplicationQuatationFormModel GetConfirmQuatationFormProductsForQuatation(long applicationID)
        {
            ApplicationQuatationFormModel applicationQuatationModel = new ApplicationQuatationFormModel();
            applicationQuatationModel.Products = new List<QuatationFormModel>();
            ApplicationForm form = GetEntities<ApplicationForm>(p => p.ApplicationID == applicationID).FirstOrDefault();
            if (!form.ApplicationProduct.IsLoaded)
            {
                form.ApplicationProduct.Load();
            }
            if (!form.UserReference.IsLoaded)
            {
                form.UserReference.Load();
            }
            foreach (ApplicationProduct product in form.ApplicationProduct)
            {
                if (!product.QuatationForm.IsLoaded)
                {
                    product.QuatationForm.Load();
                }
            }
            applicationQuatationModel.Client = form.User;
            applicationQuatationModel.RunningNumber = form.RunningNumber;
            applicationQuatationModel.ApplicationCode = form.ApplicationCode;
            applicationQuatationModel.ContactPhone = form.User.UserPhone;
            applicationQuatationModel.ReceiveTime = form.ReceiveDateTime.HasValue ? form.ReceiveDateTime.Value : DateTime.Now;
            applicationQuatationModel.QuatationTime = form.QuatationDatetime.HasValue ? form.QuatationDatetime.Value : DateTime.Now;

            List<ApplicationProduct> quoteProducts = form.ApplicationProduct.Where(p => p.QuatationForm.Count() > 0 && !p.SendBackTime.HasValue && p.BLXX != null && p.ReasonOfCost != null).ToList();
            foreach (ApplicationProduct product in quoteProducts)
            {
                if (!product.QuatationForm.IsLoaded)
                {
                    product.QuatationForm.Load();
                }
                //p => p.QuatationForm.Where(q => !q.IsBWBA.HasValue || (q.IsBWBA.HasValue && !q.IsBWBA.Value)).Count() > 0 && !p.IsDecideToRepair.HasValue && !p.SendBackTime.HasValue && p.BLXX != null && p.ReasonOfCost != null
                //if (product.QuatationForm.Count > 0 && !product.IsDecideToRepair.HasValue &&
                //    !product.SendBackTime.HasValue && product.BLXX != null && product.ReasonOfCost != null)
                //{
                    if (!product.ProductTypeReference.IsLoaded)
                    {
                        product.ProductTypeReference.Load();
                    }
                    QuatationFormModel model = new QuatationFormModel();

                    if (!product.ReturnToFactoryForm.IsLoaded)
                    {
                        product.ReturnToFactoryForm.Load();
                    }
                    if (product.ReturnToFactoryForm.Count > 0)
                    {
                        model.IsReturnToFactory = true;
                    }

                    model.RMACode = form.ApplicationCode;
                    model.ReceiveTime = form.ReceiveDateTime.Value.ToString("yyyy-MM-dd");
                    model.ProductType = product.ProductType.ProductTypeName;
                    model.ProductSerialNumber = product.ProductSerialNumber;
                    model.RepairAccessory = string.Empty;
                    model.BLXX = product.BLXX;
                    model.ProblemDescription = product.ProductProblemDescription;
                    if (model.IsReturnToFactory == true)
                    {
                        //model.Cost = product.Cost.Value;
                        //model.RepairAccessory = product.RepairAccessory;
                        //applicationQuatationModel.TotalPrices = model.Cost;
                    }
                    else
                    {
                        model.Cost = 0;
                    }

                    model.Remark = product.Remark;
                    model.PayReason = string.Empty;
                    //if (!product.QuatationForm.IsLoaded)
                    //{
                    //    product.QuatationForm.Load();
                    //}
                    foreach (QuatationForm quaForm in product.QuatationForm)
                    {
                        if (string.IsNullOrEmpty(model.RepairAccessory))
                        {
                            model.RepairAccessory += quaForm.AccessoryName;
                        }
                        else
                        {
                            model.RepairAccessory += "," + quaForm.AccessoryName;
                        }
                        if (quaForm.IsBWBA != true)
                        {
                            model.Cost += quaForm.Cost;
                        }
                        if (quaForm.Count.HasValue)
                        {
                            model.Count += quaForm.Count.Value;
                        }
                        else
                        {
                            model.Count += 1;
                        }
                        if (string.IsNullOrEmpty(model.PayReason))
                        {
                            model.PayReason += quaForm.Reason;
                        }
                        else
                        {
                            model.PayReason += "," + quaForm.Reason;
                        }
                        if (quaForm.IsBWBA != true)
                        {
                            applicationQuatationModel.TotalPrices += quaForm.Cost;
                        }
                    }

                    applicationQuatationModel.Products.Add(model);
                //}
            }
            return applicationQuatationModel;
        }

       
        public User GetClientByApplicationID(long applicationID)
        {
            ApplicationForm form = GetEntities<ApplicationForm>(p => p.ApplicationID == applicationID).FirstOrDefault();

            if (!form.UserReference.IsLoaded)
            {
                form.UserReference.Load();
            }
            return form.User;
        }

        public ApplicationQuatationFormModel GetQuatationFormModelProducts(long applicationID)
        {
            ApplicationQuatationFormModel applicationQuatationModel = new ApplicationQuatationFormModel();
            applicationQuatationModel.Products = new List<QuatationFormModel>();
            ApplicationForm form = GetEntities<ApplicationForm>(p => p.ApplicationID == applicationID).FirstOrDefault();
            if (!form.ApplicationProduct.IsLoaded)
            {
                form.ApplicationProduct.Load();
            }

            if (!form.UserReference.IsLoaded)
            {
                form.UserReference.Load();
            }
            applicationQuatationModel.Client = form.User;
            applicationQuatationModel.RunningNumber = form.RunningNumber;
            applicationQuatationModel.ApplicationCode = form.ApplicationCode;

            List<ApplicationProduct> products = form.ApplicationProduct.Where(p => p.IsQuotePrice == true && p.IsDecideToRepair == true).ToList();
            foreach (ApplicationProduct product in products)
            {
                if (product.IsQuotePrice == true)
                {
                    if (!product.ProductTypeReference.IsLoaded)
                    {
                        product.ProductTypeReference.Load();
                    }
                    if (!product.UserReference.IsLoaded)
                    {
                        product.UserReference.Load();
                    }
                    QuatationFormModel model = new QuatationFormModel();

                    //if (!product.ReturnToFactoryForm.IsLoaded)
                    //{
                    //    product.ReturnToFactoryForm.Load();
                    //}
                    //if (product.ReturnToFactoryForm.Count > 0)
                    //{
                    //    model.IsReturnToFactory = true;
                    //}

                    model.RMACode = form.ApplicationCode;
                    model.ReceiveTime = form.ReceiveDateTime.Value.ToString("yyyy-MM-dd");
                    model.ProductType = product.ProductType.ProductTypeName;
                    model.ProductSerialNumber = product.ProductSerialNumber;
                    model.ProductVersionNumber = product.ProductVersionNumber;
                    model.ProductRepairType = product.ProductRepairType;
                    model.RepairAccessory = string.Empty;
                    model.Count = product.ProductCount;
                    //if (model.IsReturnToFactory == true)
                    //{
                    //    model.Cost = product.Cost.Value;
                    //    model.RepairAccessory = product.RepairAccessory;
                    //    applicationQuatationModel.TotalPrices = model.Cost;
                    //}
                    //else
                    //{
                    //    model.Cost = 0;
                    //}

                    model.Remark = product.Remark;
                    model.PayReason = string.Empty;
                    model.Engineer = product.User.ContactPerson;
                    if (!product.QuatationForm.IsLoaded)
                    {
                        product.QuatationForm.Load();
                    }
                    foreach (QuatationForm quaForm in product.QuatationForm)
                    {
                        if (string.IsNullOrEmpty(model.RepairAccessory))
                        {
                            model.RepairAccessory += quaForm.AccessoryName;
                        }
                        else
                        {
                            model.RepairAccessory += "," + quaForm.AccessoryName;
                        }
                        model.Cost += quaForm.Cost;
                        if (string.IsNullOrEmpty(model.PayReason))
                        {
                            model.PayReason += quaForm.Reason;
                        }
                        else
                        {
                            model.PayReason += "," + quaForm.Reason;
                        }
                        // Chen Pu: 2011-08-23
                        // 朱珠(24332263) 17:50:59 
                        // 保外备案的、特服的、不维修的，应收里都不能计算
                        if (!quaForm.ApplicationProductReference.IsLoaded)
                        {
                            quaForm.ApplicationProductReference.Load();
                        }
                        if (!quaForm.ApplicationProduct.SpecialServiceProduct.IsLoaded)
                        {
                            quaForm.ApplicationProduct.SpecialServiceProduct.Load();
                        }
                        if ( quaForm.IsBWBA != true &&
                            (quaForm.ApplicationProduct.IsDecideToRepair.HasValue && quaForm.ApplicationProduct.IsDecideToRepair.Value) &&
                            (quaForm.ApplicationProduct.SpecialServiceProduct != null))
                        {
                            applicationQuatationModel.TotalPrices += quaForm.Cost;
                        }
                    }

                    applicationQuatationModel.Products.Add(model);
                }
            }
            return applicationQuatationModel;
        }

        public List<QuatationFormModel> GetQuatationFormModelProductsOnNoRepair(long applicationID)
        {
            List<QuatationFormModel> result = new List<QuatationFormModel>();
            ApplicationForm form = GetEntities<ApplicationForm>(p => p.ApplicationID == applicationID).FirstOrDefault();
            if (!form.ApplicationProduct.IsLoaded)
            {
                form.ApplicationProduct.Load();
            }

            List<ApplicationProduct> products = form.ApplicationProduct.Where(p => p.IsQuotePrice == true && p.IsDecideToRepair == false).ToList();
            foreach (ApplicationProduct product in products)
            {
                if (product.IsQuotePrice == true)
                {
                    if (!product.ProductTypeReference.IsLoaded)
                    {
                        product.ProductTypeReference.Load();
                    }
                    if (!product.UserReference.IsLoaded)
                    {
                        product.UserReference.Load();
                    }
                    QuatationFormModel model = new QuatationFormModel();

                    model.RMACode = form.ApplicationCode;
                    model.ReceiveTime = form.ReceiveDateTime.Value.ToString("yyyy-MM-dd");
                    model.ProductType = product.ProductType.ProductTypeName;
                    model.ProductSerialNumber = product.ProductSerialNumber;
                    model.ProductVersionNumber = product.ProductVersionNumber;
                    model.ProductRepairType = product.ProductRepairType;
                    model.RepairAccessory = string.Empty;
                    model.Count = product.ProductCount;

                    model.Remark = product.Remark;
                    model.PayReason = string.Empty;
                    model.Engineer = product.User.ContactPerson;
                    if (!product.QuatationForm.IsLoaded)
                    {
                        product.QuatationForm.Load();
                    }
                    foreach (QuatationForm quaForm in product.QuatationForm)
                    {
                        if (string.IsNullOrEmpty(model.RepairAccessory))
                        {
                            model.RepairAccessory += quaForm.AccessoryName;
                        }
                        else
                        {
                            model.RepairAccessory += "," + quaForm.AccessoryName;
                        }
                        model.Cost += quaForm.Cost;
                        if (string.IsNullOrEmpty(model.PayReason))
                        {
                            model.PayReason += quaForm.Reason;
                        }
                        else
                        {
                            model.PayReason += "," + quaForm.Reason;
                        }
                    }

                    result.Add(model);
                }
            }
            return result;
        }

        public List<ApplicationProduct> getAllRepairingProductsByUser(User user)
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => (p.Status == "待修" || p.Status == "已付款待修") && p.DistributeDateTime != null && ((Convert.ToDateTime(p.DistributeDateTime) > DateTime.Now.AddDays(-2))));
            if (!user.UserTypeReference.IsLoaded)
            {
                user.UserTypeReference.Load();
            }

            if (user.UserType.ID == (int)RoleType.Engineer)
            {
                products = products.Where(p => p.User != null && p.User.UserID == user.UserID);
            }
            foreach (ApplicationProduct productEntity in products)
            {
                if (!productEntity.ApplicationFormReference.IsLoaded)
                {
                    productEntity.ApplicationFormReference.Load();
                }
                if (!productEntity.ApplicationForm.UserReference.IsLoaded)
                {
                    productEntity.ApplicationForm.UserReference.Load();
                }
            }

            return products.ToList();
        }

        //private bool IsFinishQuatation(ApplicationForm applicationForm)
        //{
        //    bool flug = true;
        //    if (!applicationForm.ApplicationProduct.IsLoaded)
        //    {
        //        foreach (ApplicationProduct product in applicationForm.ApplicationProduct)
        //        {
        //            if (!product.IsQuotePrice.HasValue)
        //            {
        //                flug = false;
        //            }
        //        }
        //    }

        //    return flug;
        //}       

        public void FinishMaintains(long applicationID)
        {
            ApplicationForm application = GetEntities<ApplicationForm>(a => a.ApplicationID == applicationID).FirstOrDefault();
            if (IsFinishMaintainApplicatonForm(application))
            {
                application.Status = "维修完毕待发货";
                application.CompleteDateTime = DateTime.Now;
                UpdateEntity(application);
            }
        }

        public void FinishMaintainProduct(ApplicationProduct product)
        {
            UpdateEntity(product);

            if (!product.ApplicationFormReference.IsLoaded)
            {
                product.ApplicationFormReference.Load();
            }
            if (IsFinishMaintainApplicatonForm(product.ApplicationForm))
            {
                product.ApplicationForm.Status = "维修完毕待发货";
                product.ApplicationForm.CompleteDateTime = DateTime.Now;
                UpdateEntity(product.ApplicationForm);
            }
        }

        public void CompleteApplicationProductRepair(long applicationProductID, string fromsource)
        {
            ApplicationProduct applicationProduct = GetEntities<ApplicationProduct>().Where(a => a.ApplicationProductID == applicationProductID).FirstOrDefault();
            applicationProduct.Status = "维修完毕待发货";
            applicationProduct.RepairCompleteDateTime = DateTime.Now;
            UpdateEntity(applicationProduct);

            ChangeLogService changeLogService = new ChangeLogService();
            string changeContent = string.Format("产品维修完毕待发货 {0}", fromsource);
            changeLogService.AddChangeLog(ChangeLogType.ApplicationProduct, applicationProductID.ToString(), changeContent);
        }

        public void DeductAccessoryUseTimes(ApplicationProduct product)
        {
            // 扣除零件个数
            if (!string.IsNullOrEmpty(product.ReasonToProblem))
            {
                string[] blyyArrary = product.ReasonToProblem.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                string[] blljArrary = product.RepairAccessory.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
                string[] ljwzArrary = product.AccessoryPlace.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                for (int index = 0; index < blyyArrary.Length; index++)
                {
                    AccessoryService service = new AccessoryService();
                    if (!product.ApplicationFormReference.IsLoaded)
                    {
                        product.ApplicationFormReference.Load();
                    }
                    if (!product.ApplicationForm.ServiceStationReference.IsLoaded)
                    {
                        product.ApplicationForm.ServiceStationReference.Load();
                    }
                    switch (blyyArrary[index])
                    {
                        case "TO5":
                        case "F/W":
                            break;
                        case "P08":
                            service.UseAccessoryInRepairProcess(1, blljArrary[index], product.ApplicationForm.ServiceStation.ID);
                            break;
                        case "C12":
                            string[] currentAccessoryPlaceArrary = ljwzArrary[index].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                            service.UseAccessoryInRepairProcess(currentAccessoryPlaceArrary.Length, blljArrary[index], product.ApplicationForm.ServiceStation.ID);
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// Chen Pu:
        /// </summary>
        /// <param name="applicationForm"></param>
        /// <returns></returns>
        public void DeleteProduct(long productID)
        {
            DeleteEntities<ApplicationProduct>(p => p.ApplicationProductID == productID, Guid.Empty);
        }

        private bool IsFinishMaintainApplicatonForm(ApplicationForm applicationForm)
        {
            bool flug = true;
            if (!applicationForm.ApplicationProduct.IsLoaded)
            {
                applicationForm.ApplicationProduct.Load();
            }

            foreach (ApplicationProduct product in applicationForm.ApplicationProduct)
            {
                if (product.Status != "维修完毕待发货")
                {
                    flug = false;
                    break;
                }
            }
            if (applicationForm.Status.Equals("待付款确认"))
            {
                flug = false;
            }
            return flug;
        }

        public List<ApplicationProduct> GetAllBJXXProduct(string keyword)
        {
            IQueryable<ApplicationProduct> productList = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationType.StartsWith("B") && p.ApplicationForm.IsSubmit == true);
            if (!string.IsNullOrEmpty(keyword))
            {
                productList = productList.Where(p => p.ApplicationForm.RunningNumber.Contains(keyword) || p.ApplicationForm.User.FullName.Contains(keyword) || p.SPCode.Contains(keyword) || p.ProductType.ProductTypeName.Contains(keyword) || p.ProductSerialNumber.Contains(keyword));
            }

            foreach (ApplicationProduct product in productList)
            {
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
            }

            return productList.ToList();
        }

        public List<ApplicationProduct> GetBJXXProductByStatus(string status)
        {
            List<ApplicationProduct> productList = GetEntities<ApplicationProduct>(p => p.Status == status && (p.ApplicationForm.ApplicationType.StartsWith("B")) && p.ApplicationForm.IsSubmit == true).ToList();
            foreach (ApplicationProduct product in productList)
            {
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
                if (!product.ProblemTypeReference.IsLoaded)
                {
                    product.ProblemTypeReference.Load();
                }
            }

            return productList;
        }

        public List<ApplicationProduct> GetBJXXProductByStatusAndEngineer(string status, long userid)
        {
            List<ApplicationProduct> productList = GetEntities<ApplicationProduct>(p => p.Status == status && (p.ApplicationForm.ApplicationType.StartsWith("B")) && p.ApplicationForm.IsSubmit == true
                && p.User.UserID == userid).ToList();
            foreach (ApplicationProduct product in productList)
            {
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
                if (!product.ProblemTypeReference.IsLoaded)
                {
                    product.ProblemTypeReference.Load();
                }
            }

            return productList;
        }

        public List<ApplicationProduct> GetBJXXProductForEngineer(long userid)
        {
            List<ApplicationProduct> productList = GetEntities<ApplicationProduct>(p => p.Status == "备件已归还待验证" && p.User.UserID == userid && (p.ApplicationForm.ApplicationType.Equals("BB") || p.ApplicationForm.ApplicationType.Equals("BD")) && p.ApplicationForm.IsSubmit == true).ToList();
            foreach (ApplicationProduct product in productList)
            {
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
            }

            return productList;
        }

        internal int GetNumberOfBJXXProduct(string code)
        {
            return GetEntities<ApplicationProduct>(p => p.SPCode.StartsWith(code) != null).Count();
        }

        public List<ApplicationProductOverDueModel> GetApplicationProductByRoleAndUserID(int roleNumber, long userID, string keyword)
        {
            List<ApplicationProductOverDueModel> applicationProductModelList = new List<ApplicationProductOverDueModel>();
            int repairDays = 0;
            List<string> statusList = new List<string>();
            if (roleNumber == (int)RoleType.CustomerManager || roleNumber == (int)RoleType.CustomerMonitor || roleNumber == (int)RoleType.Manager || roleNumber == (int)RoleType.Administrator)
            {
                IQueryable<ApplicationProduct> applicationProductsOverDue = GetEntities<ApplicationProduct>(a => a.DistributeDateTime.HasValue && !a.RepairCompleteDateTime.HasValue && a.ApplicationForm.RMANOGenerateDateTime.HasValue && a.User != null);
                foreach (ApplicationProduct product in applicationProductsOverDue)
                {
                    if (!product.ApplicationFormReference.IsLoaded)
                    {
                        product.ApplicationFormReference.Load();
                    }

                    repairDays = GetRepairDays(product.ApplicationForm.RMANOGenerateDateTime.Value);
                    if (repairDays >= 2)
                    {
                        if (!product.ApplicationForm.UserReference.IsLoaded)
                        {
                            product.ApplicationForm.UserReference.Load();
                        }
                        if (!product.UserReference.IsLoaded)
                        {
                            product.UserReference.Load();
                        }
                        statusList = GetApplicationProductRepairStatus(product);
                        applicationProductModelList.Add(new ApplicationProductOverDueModel
                        {
                            ApplicationID = product.ApplicationForm.ApplicationID,
                            ApplicationCode = product.ApplicationForm.ApplicationCode,
                            Customer = product.ApplicationForm.User.FullName,
                            DistributeDate = product.ApplicationForm.DistributeDateTime.HasValue ? product.ApplicationForm.DistributeDateTime.Value.ToString("yyyy-MM-dd HH:mm") : "",
                            PhoneNumber = product.ApplicationForm.User.UserPhone,
                            RepairDay = repairDays,
                            Status = statusList[0],
                            Statustip = statusList[1],
                            QuoteStatus = statusList[2],
                            QuoteStatusTip = statusList[3],
                            Engineer = product.User.ContactPerson
                        });
                    }
                }
            }
            else
            {
                IQueryable<ApplicationProduct> applicationProductsOverDue = GetEntities<ApplicationProduct>(a => a.DistributeDateTime.HasValue && !a.RepairCompleteDateTime.HasValue && a.User != null && a.User.UserID == userID &&
                    a.ApplicationForm.RMANOGenerateDateTime.HasValue);
                foreach (ApplicationProduct product in applicationProductsOverDue)
                {
                    if (!product.ApplicationFormReference.IsLoaded)
                    {
                        product.ApplicationFormReference.Load();
                    }

                    repairDays = GetRepairDays(product.ApplicationForm.RMANOGenerateDateTime.Value);
                    if (repairDays >= 2)
                    {
                        if (!product.ApplicationForm.UserReference.IsLoaded)
                        {
                            product.ApplicationForm.UserReference.Load();
                        }
                        if (!product.UserReference.IsLoaded)
                        {
                            product.UserReference.Load();
                        }
                        statusList = GetApplicationProductRepairStatus(product);
                        applicationProductModelList.Add(new ApplicationProductOverDueModel
                        {
                            ApplicationID = product.ApplicationForm.ApplicationID,
                            ApplicationCode = product.ApplicationForm.ApplicationCode,
                            Customer = product.ApplicationForm.User.FullName,
                            DistributeDate = product.ApplicationForm.DistributeDateTime.HasValue ? product.ApplicationForm.DistributeDateTime.Value.ToString("yyyy-MM-dd HH:mm") : "",
                            PhoneNumber = product.ApplicationForm.User.UserPhone,
                            RepairDay = repairDays,
                            Status = statusList[0],
                            Statustip = statusList[1],
                            QuoteStatus = statusList[2],
                            QuoteStatusTip = statusList[3],
                            Engineer = product.User.ContactPerson
                        });
                    }
                }
            }
            if (!string.IsNullOrEmpty(keyword))
            {
                applicationProductModelList = applicationProductModelList.Where(p => p.ApplicationCode.Contains(keyword) || p.Customer.Contains(keyword) || p.Engineer.Contains(keyword) || p.RepairDay.ToString().Contains(keyword)).ToList();
            }

            return applicationProductModelList.OrderBy(p => p.RepairDay).ToList();
        }

        public List<string> GetApplicationProductRepairStatus(ApplicationProduct product)
        {
            List<string> statusList = new List<string>();
            if (!product.UpgradeForm.IsLoaded)
            {
                product.UpgradeForm.Load();
            }
            if (!product.ReturnToFactoryForm.IsLoaded)
            {
                product.ReturnToFactoryForm.Load();
            }
            if (!product.SparePartApplyForm.IsLoaded)
            {
                product.SparePartApplyForm.Load();
            }
            if (!product.ApplicationFormReference.IsLoaded)
            {
                product.ApplicationFormReference.Load();
            }

            #region 显示维修状态及Tooltip, 设置与维修状态相关的按钮状态
            string status = "";
            string tooltip = "";
            if(!product.UpgradeForm.IsLoaded)
            {
                product.UpgradeForm.Load();
            }
            if(!product.ReturnToFactoryForm.IsLoaded)
            {
                product.ReturnToFactoryForm.Load();
            }
            if (!product.SparePartApplyForm.IsLoaded)
            {
                product.SparePartApplyForm.Load();
            }
            if(!product.ApplicationFormReference.IsLoaded)
            {
                product.ApplicationFormReference.Load();
            }
            #region 升级申请单
            if (product.UpgradeForm.Count > 0)
            {
                UpgradeForm upgradeForm = product.UpgradeForm.FirstOrDefault();
                tooltip = string.Format("升级申请时间：{0}，当前状态：{1}", upgradeForm.ApplyTime.Value.ToString("yyyy-MM-dd HH:mm"), upgradeForm.Status);
                // 升级-不同意
                if (upgradeForm.Status.Equals("升级-不同意"))
                {
                    status = "升级驳回-待修";
                    if (upgradeForm.CompleteTime.HasValue)
                    {
                        tooltip += string.Format(", 驳回时间：{0}， 驳回原因:{1}", upgradeForm.CompleteTime.Value.ToString("yyyy-MM-dd HH:mm"), upgradeForm.Suggestion);
                    }
                }
                // 升级已经完成
                else if (upgradeForm.Status.Equals("升级完毕") ||
                    upgradeForm.Status.Equals("升级-平台收货确认"))
                {
                    status = "升级完毕";
                }
                else if (upgradeForm.Status.Equals("升级-待修"))
                {
                    status = "升级-待修";
                }
                else
                {
                    status = "升级申请中";
                }
            }
            #endregion
            #region 返厂申请单
            if (product.ReturnToFactoryForm.Count > 0)
            {
                ReturnToFactoryForm returnToFactoryForm = product.ReturnToFactoryForm.FirstOrDefault();

                if (!string.IsNullOrEmpty(status))
                {
                    status += ", ";
                    tooltip += ", ";
                }
                status += "返厂维修中";
                tooltip += string.Format("返厂申请时间：{0}, 当前状态：{1}", returnToFactoryForm.ApplyDate.Value.ToString("yyyy-MM-dd HH:mm"), returnToFactoryForm.Status);
            }
            #endregion
            #region 备件申请单
            if (product.SparePartApplyForm.Count > 0)
            {
                SparePartApplyForm sparePartApplyForm = product.SparePartApplyForm.FirstOrDefault();
                if (sparePartApplyForm.Status.Equals("备件-不同意"))
                {
                    if (!string.IsNullOrEmpty(status))
                    {
                        status += ", ";
                    }
                    status += "备件驳回-待修";
                }
                else if (sparePartApplyForm.Status.Equals("备件-已归还"))
                {
                    if (!string.IsNullOrEmpty(status))
                    {
                        status += ", ";
                    }
                    status += "备件已归还-待修";
                }
                else
                {
                    if (!string.IsNullOrEmpty(status))
                    {
                        status += ", ";
                    }
                    status += "备件申请中";
                }

                if (!string.IsNullOrEmpty(status))
                {
                    tooltip += ", ";
                }
                tooltip += string.Format("备件申请时间：{0}, 当前状态:{1}", sparePartApplyForm.ApplyTime.Value.ToString("yyyy-MM-dd HH:mm"), sparePartApplyForm.Status);
            }
            #endregion

            if (product.RepairCompleteDateTime.HasValue)
            {
                status = product.Status;
                if (product.SendBackTime.HasValue)
                {
                    tooltip += "发货时间：" + product.SendBackTime.Value.ToString("yyyy-MM-dd HH:mm");
                }
            }

            // 显示维修状态及Tooltip
            if (string.IsNullOrEmpty(status))
            {
                status = "待修";
                tooltip = "派单时间：" + product.DistributeDateTime.Value.ToString("yyyy-MM-dd HH:mm");
            }

            #endregion

            #region 显示报价状态，设置于报价相关的按钮状态
            // （针对新数据，增加了ApplicationForm.QuatationDatetime） 报价状态
            string quotePrice = "";
            if (!(product.IsQuotePrice.HasValue && product.IsQuotePrice.Value))
            {
                quotePrice = "未报价";
            }
            else if (product.IsQuotePrice.HasValue && !product.QuotationDateTime.HasValue)
            {
                quotePrice = "报价中";
            }
            else if (product.IsQuotePrice.HasValue && product.QuotationDateTime.HasValue &&
                !product.ApplicationForm.QuatationDatetime.HasValue)
            {
                quotePrice = "报价完毕";
            }
            // 报价确认中
            else if (product.QuotationDateTime.HasValue &&
                 product.ApplicationForm.QuatationDatetime.HasValue &&
                !product.ApplicationForm.ConfirmQuatationCompleteDate.HasValue)
            {
                quotePrice = "报价确认中";
            }
            // 已确认报价
            else if (product.ApplicationForm.ConfirmQuatationCompleteDate.HasValue)
            {
                // 接受报价维修
                if (product.IsDecideToRepair.HasValue && product.IsDecideToRepair.Value)
                {
                    quotePrice = "接受报价，待付款";

                    if (!product.ApplicationForm.GatheringReference.IsLoaded)
                    {
                        product.ApplicationForm.GatheringReference.Load();
                    }
                    if (product.ApplicationForm.Gathering != null)
                    {
                        quotePrice = "已收款";
                    }
                }
                else
                {
                    quotePrice = "不接受报价";
                }
            }
            string quotePriceTooltip = "";
            if (product.QuotationDateTime.HasValue)
            {
                quotePriceTooltip = "报价时间：" + product.QuotationDateTime.Value.ToString("yyyy-MM-dd HH:mm");
            }
            if (product.ConfirmQuotationDateTime.HasValue)
            {
                quotePriceTooltip += "， 客户确认时间：" + product.ConfirmQuotationDateTime.Value.ToString("yyyy-MM-dd HH:mm");
            }
            if (!product.ApplicationForm.GatheringReference.IsLoaded)
            {
                product.ApplicationForm.GatheringReference.Load();
            }
            if (product.ApplicationForm.Gathering != null)
            {
                quotePriceTooltip += "， 收款时间：" + product.ApplicationForm.Gathering.PayDateTime.Value.ToString("yyyy-MM-dd HH:mm");
            }
            #endregion
            statusList.Add(status);
            statusList.Add(tooltip);
            statusList.Add(quotePrice);
            statusList.Add(quotePriceTooltip);
            return statusList;
        }

        private int GetRepairDays(DateTime applyDateTime)
        {
            DateTime endTime = DateTime.Now.Date;
            int days = 0;
            for (DateTime startTime = applyDateTime.Date; startTime < endTime; startTime = startTime.AddDays(1))
            {
                if (startTime.DayOfWeek != DayOfWeek.Saturday && startTime.DayOfWeek != DayOfWeek.Sunday)
                {
                    days++;
                }
            }

            return days;
        }

        public List<MaintainRecordBaseOnProblemTypeModel> GetMaintainRecordsByProductType(string productType, string year, string month)
        {
            List<MaintainRecordBaseOnProblemTypeModel> modellist = new List<MaintainRecordBaseOnProblemTypeModel>();
            if (string.IsNullOrEmpty(productType))
            {
                List<ProductType> productTypelist = GetAllProductType();
                foreach (ProductType type in productTypelist)
                {
                    MaintainRecordBaseOnProblemTypeModel model = new MaintainRecordBaseOnProblemTypeModel();
                    model.ProductType = type.ProductTypeName;
                    model.RepairTimes = GetProductNumberByProductTypeYearMonth(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month));
                    model.A1 = GetProductNumberByProductTypeYearMonthRemarkA(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "有缺陷");
                    model.A2 = GetProductNumberByProductTypeYearMonthRemarkA(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "正常损坏");
                    model.A3 = GetProductNumberByProductTypeYearMonthRemarkA(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "使用不当");
                    model.A4 = GetProductNumberByProductTypeYearMonthRemarkA(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "非人为(不可抗力等)");
                    model.B1 = GetProductNumberByProductTypeYearMonthRemarkB(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "环境不适");
                    model.B2 = GetProductNumberByProductTypeYearMonthRemarkB(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "操作不当");
                    model.B3 = GetProductNumberByProductTypeYearMonthRemarkB(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "正常损坏");
                    model.C1 = GetProductNumberByProductTypeYearMonthRemarkC(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "固件Bug");
                    model.C2 = GetProductNumberByProductTypeYearMonthRemarkC(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "正常升级");
                    model.RetestOK = GetProductNumberByProductTypeYearMonthRemarkD(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "RestestOK");
                    model.Other = GetProductNumberByProductTypeYearMonthRemarkE(type.ProductTypeID, Convert.ToInt32(year), Convert.ToInt32(month), "其它原因");
                    modellist.Add(model);
                }
            }

            return modellist;
        }

        private int GetProductNumberByProductTypeYearMonthRemarkE(int typeID, int year, int month, string remark)
        {
            IQueryable<ApplicationProduct> productList = GetProductNumberByProductTypeYearMonthlist(typeID, year, month);
            return productList.Where(p => p.ProblemAnalyze.E == remark).Count();
        }

        private int GetProductNumberByProductTypeYearMonthRemarkD(int typeID, int year, int month, string remark)
        {
            IQueryable<ApplicationProduct> productList = GetProductNumberByProductTypeYearMonthlist(typeID, year, month);
            return productList.Where(p => p.ProblemAnalyze.D == remark).Count();
        }

        private int GetProductNumberByProductTypeYearMonthRemarkC(int typeID, int year, int month, string remark)
        {
            IQueryable<ApplicationProduct> productList = GetProductNumberByProductTypeYearMonthlist(typeID, year, month);
            return productList.Where(p => p.ProblemAnalyze.C == remark).Count();
        }

        private int GetProductNumberByProductTypeYearMonthRemarkB(int typeID, int year, int month, string remark)
        {
            IQueryable<ApplicationProduct> productList = GetProductNumberByProductTypeYearMonthlist(typeID, year, month);
            return productList.Where(p => p.ProblemAnalyze.B == remark).Count();
        }

        private int GetProductNumberByProductTypeYearMonthRemarkA(int typeID, int year, int month, string remark)
        {
            IQueryable<ApplicationProduct> productList = GetProductNumberByProductTypeYearMonthlist(typeID, year, month);
            return productList.Where(p => p.ProblemAnalyze.A == remark).Count();
        }

        private int GetProductNumberByProductTypeYearMonth(int typeID, int year, int month)
        {
            return GetEntities<ApplicationProduct>(p => p.ProductType.ProductTypeID == typeID && p.ApplicationForm.ApplicationDateTime.Value.Year == year && p.ApplicationForm.ApplicationDateTime.Value.Month == month).Count();
        }

        private IQueryable<ApplicationProduct> GetProductNumberByProductTypeYearMonthlist(int typeID, int year, int month)
        {
            return GetEntities<ApplicationProduct>(p => p.ProductType.ProductTypeID == typeID && p.ApplicationForm.ApplicationDateTime.Value.Year == year && p.ApplicationForm.ApplicationDateTime.Value.Month == month);
        }

        public IQueryable<ApplicationProduct> GetProductByStartDateAndEndDate(string start, string end)
        {
            IQueryable<ApplicationProduct> prodcuts = GetEntities<ApplicationProduct>();
            if (!string.IsNullOrEmpty(start))
            {
                DateTime startDate = Convert.ToDateTime(start + " 00:00:00");
                prodcuts = prodcuts.Where(p => p.ApplicationForm.ApplicationDateTime > startDate);
            }
            if (!string.IsNullOrEmpty(end))
            {
                DateTime endDate = Convert.ToDateTime(end + " 23:59:59");
                prodcuts = prodcuts.Where(p => p.ApplicationForm.ApplicationDateTime < endDate);
            }
            foreach (ApplicationProduct product in prodcuts)
            {
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.ApplicationForm.ServiceStationReference.IsLoaded)
                {
                    product.ApplicationForm.ServiceStationReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
            }

            return prodcuts.OrderByDescending(p => p.ApplicationForm.ApplicationDateTime.Value);
        }

        public List<ProductTypeMaintainModel> GetProdcutMaintainByProductType(int year)
        {
            int sumNumber = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationDateTime.Value.Year == year).Count();
            List<ProductTypeMaintainModel> ptmms = new List<ProductTypeMaintainModel>();
            List<ProductType> allProductType = GetEntities<ProductType>().ToList();
            foreach (ProductType type in allProductType)
            {
                ProductTypeMaintainModel model = new ProductTypeMaintainModel();
                model.ProductTypeName = type.ProductTypeName;
                model.Number = GetEntities<ApplicationProduct>(p => p.ProductType.ProductTypeID == type.ProductTypeID && p.ApplicationForm.ApplicationDateTime.Value.Year == year).Count();
                model.Persents = Math.Round(model.Number * 100 / Convert.ToDouble(sumNumber), 2);
                model.SumNumber = sumNumber;
                ptmms.Add(model);
            }

            return ptmms;
        }

        public IQueryable<ApplicationProduct> GetProductByYearMonthService(int year, int month, int servicestation)
        {
            return GetEntities<ApplicationProduct>(p => p.ApplicationForm.Gathering.PayDateTime.Value.Year == year
                && p.ApplicationForm.Gathering.PayDateTime.Value.Month == month
                && p.ApplicationForm.ServiceStation.ID == servicestation && p.IsDecideToRepair.HasValue && p.IsDecideToRepair.Value == true);
        }

        public IQueryable<ApplicationProduct> GetProductByGatheringInterval(int year, int month, int tyear, int tmonth, int servicestation)
        {
            if (servicestation > 0)
            {
                return GetEntities<ApplicationProduct>(p => p.ApplicationForm.Gathering.PayDateTime.Value.Year >= year
                    && p.ApplicationForm.Gathering.PayDateTime.Value.Month >= month
                    && p.ApplicationForm.Gathering.PayDateTime.Value.Year <= tyear
                    && p.ApplicationForm.Gathering.PayDateTime.Value.Month <= tmonth
                    && p.ApplicationForm.ServiceStation.ID == servicestation
                    && p.IsDecideToRepair.HasValue && p.IsDecideToRepair.Value == true);
            }
            else
            {
                return GetEntities<ApplicationProduct>(p => p.ApplicationForm.Gathering.PayDateTime.Value.Year >= year
                    && p.ApplicationForm.Gathering.PayDateTime.Value.Month >= month
                    && p.ApplicationForm.Gathering.PayDateTime.Value.Year <= tyear
                    && p.ApplicationForm.Gathering.PayDateTime.Value.Month <= tmonth
                    && p.IsDecideToRepair.HasValue && p.IsDecideToRepair.Value == true);
            }
        }

        public IQueryable<ApplicationProduct> GetProductByGatheringYear(int year)
        {
            return GetEntities<ApplicationProduct>(p => p.ApplicationForm.Gathering.PayDateTime.Value.Year == year
                && p.IsDecideToRepair.HasValue && p.IsDecideToRepair == true);
        }

        public List<ApplicationProduct> GetProductReturnToFactory(int year, string providerCode)
        {
            //return GetEntities<ApplicationProduct>(p => p.ReturnToFactoryForm.Count > 0
            //    && p.IsDecideToRepair.HasValue && p.IsDecideToRepair == true);
            IQueryable<ReturnToFactoryForm> ql = GetEntities<ReturnToFactoryForm>(r => r.ReturnToFactoryQuatation.Count > 0 &&
                r.ProvideCode.Equals(providerCode) &&
                r.ProviderQuatationDate.HasValue &&
                r.ConfirmQuatationDate.HasValue &&
                r.ConfirmQuatationDate.Value.Year == year);
            List<ApplicationProduct> products = new List<ApplicationProduct>();
            foreach (ReturnToFactoryForm rf in ql)
            {
                if (!rf.ApplicationProductReference.IsLoaded)
                {
                    rf.ApplicationProductReference.Load();
                }
                if (!rf.ApplicationProduct.ApplicationFormReference.IsLoaded)
                {
                    rf.ApplicationProduct.ApplicationFormReference.Load();
                }
                if (!rf.ApplicationProduct.ProductTypeReference.IsLoaded)
                {
                    rf.ApplicationProduct.ProductTypeReference.Load();
                }
                if (!rf.ReturnToFactoryQuatation.IsLoaded)
                {
                    rf.ReturnToFactoryQuatation.Load();
                }
                ApplicationProduct product = new ApplicationProduct();
                product.ApplicationForm = rf.ApplicationProduct.ApplicationForm;
                product.ProductType = rf.ApplicationProduct.ProductType;
                product.Cost = 0;
                foreach (ReturnToFactoryQuatation q in rf.ReturnToFactoryQuatation)
                {
                    product.RepairAccessory += q.AccessoryName + ";";
                    product.Cost += Convert.ToDouble(q.Count * q.UnitPrice);
                }
                if (product.RepairAccessory.Length > 0)
                {
                    product.RepairAccessory = product.RepairAccessory.Substring(0, product.RepairAccessory.Length - 1);
                }
                product.ReasonOfCost = rf.ApplicationProduct.ReasonOfCost;
                products.Add(product);
            }
            return products;
        }

        public List<SFTJProviderModel> GetSFTJProviderModelByYear(int year)
        {
            List<SFTJProviderModel> models = new List<SFTJProviderModel>();
            ProviderService providerService = new ProviderService();
            List<Provider> providers = providerService.GetAllProvider();
            foreach (Provider pro in providers)
            {
                SFTJProviderModel model = new SFTJProviderModel();
                List<ApplicationProduct> products = GetProductReturnToFactory(year, pro.ProviderCode);
                double? inall = products.Sum(p => p.Cost);
                model.Provider = pro.ProviderName;
                model.InAll = inall.HasValue ? inall.Value : 0;
                models.Add(model);
            }

            return models;
        }

        public List<ApplicationProduct> GetProductReturnToFactoryByInterval(int year, int month, int tyear, int tmonth, string providerCode)
        {
            //IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => 
            //p.ApplicationForm.Gathering.PayDateTime.Value.Year >= year
            //&& p.ApplicationForm.Gathering.PayDateTime.Value.Month >= month
            //&& 
            //p.ApplicationForm.Gathering.PayDateTime.Value.Year <= tyear
            //&& p.ApplicationForm.Gathering.PayDateTime.Value.Month <= tmonth
            //&& p.IsDecideToRepair.HasValue && p.IsDecideToRepair.Value == true
            //&& 
            // p.ReturnToFactoryForm.Count > 0 && 
            //p.ReturnToFactoryForm.FirstOrDefault().ConfirmQuatationDate.Value.Year <= tyear &&
            //p.ReturnToFactoryForm.FirstOrDefault().ConfirmQuatationDate.Value.Month <= tmonth);
            //products = products.Where(p => p.ReturnToFactoryForm.FirstOrDefault().ConfirmQuatationDate.Value.Year >= year &&
            // p.ReturnToFactoryForm.FirstOrDefault().ConfirmQuatationDate.Value.Month >= month);
            //if (!string.IsNullOrEmpty(providerCode))
            //{
            //  products = products.Where(p => p.ReturnToFactoryForm.FirstOrDefault().ProvideCode.Equals(providerCode));
            // }
            DateTime startDate = new DateTime(year, month, 1);
            if (tmonth == 12)
            {
                tyear += 1;
                tmonth = 1;
            }
            else
            {
                tmonth += 1;
            }
            DateTime endDate = new DateTime(tyear, tmonth, 1);
            IQueryable<ReturnToFactoryForm> ql = GetEntities<ReturnToFactoryForm>(r => r.ReturnToFactoryQuatation.Count > 0 &&
                r.ProviderQuatationDate.HasValue &&
                r.ConfirmQuatationDate.HasValue &&
                r.ConfirmQuatationDate.Value > startDate && r.ConfirmQuatationDate.Value < endDate);
            if (!string.IsNullOrEmpty(providerCode))
            {
                ql = ql.Where(r => r.ProvideCode.Equals(providerCode));
            }
            List<ApplicationProduct> products = new List<ApplicationProduct>();
            foreach (ReturnToFactoryForm rf in ql)
            {
                if (!rf.ApplicationProductReference.IsLoaded)
                {
                    rf.ApplicationProductReference.Load();
                }
                if (!rf.ApplicationProduct.ApplicationFormReference.IsLoaded)
                {
                    rf.ApplicationProduct.ApplicationFormReference.Load();
                }
                if (!rf.ApplicationProduct.ProductTypeReference.IsLoaded)
                {
                    rf.ApplicationProduct.ProductTypeReference.Load();
                }
                if (!rf.ReturnToFactoryQuatation.IsLoaded)
                {
                    rf.ReturnToFactoryQuatation.Load();
                }
                ApplicationProduct product = new ApplicationProduct();
                product.ApplicationForm = rf.ApplicationProduct.ApplicationForm;
                product.ApplicationProductID = rf.ApplicationProduct.ApplicationProductID;
                product.ProductType = rf.ApplicationProduct.ProductType;
                product.Cost = 0;
                foreach (ReturnToFactoryQuatation q in rf.ReturnToFactoryQuatation)
                {
                    product.RepairAccessory += q.AccessoryName + ";";
                    product.Cost += Convert.ToDouble(q.Count * q.UnitPrice);
                }
                if (product.RepairAccessory.Length > 0)
                {
                    product.RepairAccessory = product.RepairAccessory.Substring(0, product.RepairAccessory.Length - 1);
                }
                product.ReasonOfCost = rf.ApplicationProduct.ReasonOfCost;
                products.Add(product);
            }
            return products;
        }

        public IQueryable<ApplicationProduct> GetApplicatonProductSendFaPiaoByFormID(long applicationID)
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(a => a.ApplicationForm.ApplicationID == applicationID && a.QuatationForm.Count > 0);
            return products;
        }

        public IQueryable<ApplicationProduct> GetApplicationProductHasSent()
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(a => a.IsDiaoBo.HasValue && a.IsDiaoBo == true).OrderBy(a => a.ApplicationForm.User.UserID).OrderByDescending(a => a.SendBackTime);
            foreach (ApplicationProduct product in products)
            {
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.UserReference.IsLoaded)
                {
                    product.UserReference.Load();
                }
                if (!product.RequisitionFormReference.IsLoaded)
                {
                    product.RequisitionFormReference.Load();
                }
                if (product.RequisitionForm != null)
                {
                    if (!product.RequisitionForm.LogisticCompanyReference.IsLoaded)
                    {
                        product.RequisitionForm.LogisticCompanyReference.Load();
                    }
                }
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
            }

            return products;
        }

        public IQueryable<ApplicationProduct> GetApplicationProductHasSent(int serviceStationID)
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(a => a.IsDiaoBo.HasValue && a.IsDiaoBo == true && a.ApplicationForm.ServiceStation.ID == serviceStationID).OrderBy(a => a.ApplicationForm.User.UserID).OrderByDescending(a => a.SendBackTime);
            foreach (ApplicationProduct product in products)
            {
                if (!product.ApplicationFormReference.IsLoaded)
                {
                    product.ApplicationFormReference.Load();
                }
                if (!product.UserReference.IsLoaded)
                {
                    product.UserReference.Load();
                }
                if (!product.RequisitionFormReference.IsLoaded)
                {
                    product.RequisitionFormReference.Load();
                }
                if (!product.ProductTypeReference.IsLoaded)
                {
                    product.ProductTypeReference.Load();
                }
                if (!product.ApplicationForm.UserReference.IsLoaded)
                {
                    product.ApplicationForm.UserReference.Load();
                }
            }

            return products;
        }

        public void AddQuatation(QuatationForm quatationItem)
        {
            InsertEntity(quatationItem);
        }

        public List<MaintainHistoryModel> GetApplicationProductHistoryByApplicatonFormID(long formID)
        {
            List<MaintainHistoryModel> productIDList = new List<MaintainHistoryModel>();
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationID == formID);
            foreach (ApplicationProduct product in products)
            {
                ApplicationProduct productmaintainhistory = GetEntities<ApplicationProduct>(p => p.ProductSerialNumber == product.ProductSerialNumber && p.ProductVersionNumber == p.ProductVersionNumber && p.ApplicationForm.ApplicationID != formID && p.ApplicationForm.IsSubmit == true && p.RepairCompleteDateTime.HasValue).FirstOrDefault();
                if (productmaintainhistory != null)
                {
                    productIDList.Add(new MaintainHistoryModel { ID = productmaintainhistory.ApplicationProductID, SerialNumber = productmaintainhistory.ProductSerialNumber });
                }
            }
            return productIDList;
        }

        public List<ApplicationProduct> GetProductShouldSend(long formID, long userID)
        {
            User senter = GetEntities<User>(u => u.UserID == userID).FirstOrDefault();
            if (!senter.UserTypeReference.IsLoaded)
            {
                senter.UserTypeReference.Load();
            }
            if (!senter.ServiceStationReference.IsLoaded)
            {
                senter.ServiceStationReference.Load();
            }

            ApplicationService appService = new ApplicationService();
            ApplicationForm form = appService.GetApplicationFormByID(formID);
            if (!form.ServiceStationReference.IsLoaded)
            {
                form.ServiceStationReference.Load();
            }
            if (!form.ApplicationProduct.IsLoaded)
            {
                form.ApplicationProduct.Load();
            }
            if (!form.GatheringReference.IsLoaded)
            {
                form.GatheringReference.Load();
            }
            //IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(p => p.ApplicationForm.ApplicationID == formID && p.Status == "维修完毕待发货" && 
            //    !p.SendBackTime.HasValue && 
            //    (!p.IsDecideToRepair.HasValue || 
            //    p.IsDecideToRepair == false || 
            //    (p.IsDecideToRepair == true && 
            //    (p.QuotationDateTime.HasValue && p.ConfirmQuotationDateTime.HasValue && p.ApplicationForm.Gathering != null))));

            //if (senter.ServiceStation.ID == 1 && (senter.UserType.ID == (int)RoleType.Engineer || senter.UserType.ID == (int)RoleType.Service))
            //{
            //    if (products.Where(p => p.User.ServiceStation.ID == senter.ServiceStation.ID).Count() > 0)
            //    {
            //        products = products.Where(p => p.UpgradeForm.Count == 0 || p.UpgradeForm.Count > 0 && p.UpgradeForm.FirstOrDefault().Status != "升级-不同意" && p.UpgradeForm.FirstOrDefault().SendWay == "客户");
            //    }
            //}
            //else if (senter.UserType.ID != (int)RoleType.Administrator)
            //{
            //    products = products.Where(p => !(p.UpgradeForm.Count > 0 && p.UpgradeForm.FirstOrDefault().Status != "升级-不同意" && p.UpgradeForm.FirstOrDefault().SendWay == "客户"));
            //}

            IQueryable<ApplicationProduct> products = form.ApplicationProduct.Where(p => p.RepairCompleteDateTime.HasValue && !p.SendBackTime.HasValue &&
                 ((!(p.IsQuotePrice.HasValue && p.IsQuotePrice.Value)) || !(p.IsDecideToRepair.HasValue && p.IsDecideToRepair.Value) || p.ApplicationForm.Gathering != null) &&
                 (p.UpgradeForm.Count() == 0 || p.UpgradeForm.Where(u => u.Status == "升级-不同意").Count() > 0 || p.UpgradeForm.Where(u => u.SendWay == "客户" || (u.SendWay == "平台" && u.CompleteTime.HasValue)).Count() > 0)).AsQueryable();
            
            foreach (ApplicationProduct product in products)
            {
                if (!product.UserReference.IsLoaded)
                {
                    product.UserReference.Load();
                }
            }
            return products.ToList();
        }

        public List<RepairOverdueModel> GetRepairOverdueProduct()
        {
            IQueryable<ApplicationProduct> products = GetEntities<ApplicationProduct>(a => a.DistributeDateTime.HasValue && a.Status.Contains("待修"));
            List<RepairOverdueModel> overdueModels = new List<RepairOverdueModel>();

            
            foreach (ApplicationProduct product in products)
            {
                    if (DateTimeService.CalculateDateTimeSpan(product.DistributeDateTime.Value, DateTime.Now) > 2)
                    {
                        if (!product.ApplicationFormReference.IsLoaded)
                        {
                            product.ApplicationFormReference.Load();
                        }
                        if (!product.UserReference.IsLoaded)
                        {
                            product.UserReference.Load();
                        }

                        RepairOverdueModel overdueModel = new RepairOverdueModel();
                        overdueModel.EngineerEmail = product.User.UserEmail;
                        overdueModel.EngineerName = product.User.ContactPerson;
                        overdueModel.OverdueDay = DateTimeService.CalculateDateTimeSpan(product.DistributeDateTime.Value, DateTime.Now) - 2;
                        overdueModel.RMACode = product.ApplicationForm.ApplicationCode;

                        overdueModels.Add(overdueModel);
                    }
            }

            return overdueModels;

        }

        public List<ApplicationProduct> GetAppProductByProductTypeID(int productTypeID)
        {
            return GetEntities<ApplicationProduct>().Where(s => s.ProductType.ProductTypeID == productTypeID).ToList();
        }

        public List<ApplicationProduct> GetAppProductByProblemTypeID(int problemTypeID)
        {
            return GetEntities<ApplicationProduct>().Where(s => s.ProblemType.ID == problemTypeID).ToList();
        }

        public List<ApplicationProductHistory> GetAppProductHistoryByProductTypeID(int productTypeID)
        {
            return GetEntities<ApplicationProductHistory>().Where(s => s.ProductType.ProductTypeID == productTypeID).ToList();
        }

        public List<ApplicationProductHistory> GetAppProductHistoryByProblemTypeID(int problemTypeID)
        {
            return GetEntities<ApplicationProductHistory>().Where(s => s.ProblemType.ID== problemTypeID).ToList();
        }
    }
}
